每天凌晨三點,Clawrion 會自動「睡覺」。
不是關機,是進入一個叫 dreaming 的循環:把白天累積的對話與日誌讀進來,消化、提煉、去重,再寫回長期記憶。隔天早上,它就「記得」昨天發生的事了。(老實說,當初會認真研究這個框架,一半就是被這個功能吸引——一個會做夢的系統,光聽就想裝來看看。)
它就是昨天三層架構裡的第三層。再強調一次歸屬:這個機制是框架內建的,不是我寫的。我能講的只有「它實際跑起來長什麼樣」——包含官方文件不會寫的那些:它半夜卡住的時候、它把不該記的東西記進去的時候。今天就拆開這一層,用的是使用者的視角,不是作者的。
問題昨天鋪好了:每日日誌是只進不出的流水帳,放著不管,真正該記住的(決策、教訓、偏好)會被雜訊淹沒——記憶不能只進不理。
人腦的解法是睡眠:白天的經驗在睡覺時被整理、鞏固、遺忘掉不重要的。框架直接抄了這個設計——讓系統在離峰的凌晨三點,自動跑一輪「整理」。
框架把 dreaming 拆成模仿睡眠的三個階段,各做不同的事——這個分法是它的設計,我只是用它的人:

MEMORY.md——「這週投資做了什麼」「系統修了哪個 bug」。這是最硬的整合。DREAMS.md,用比較鬆散、敘事的方式回顧當天——聽起來玄,但它的作用是把零散事件串成有脈絡的記憶,就像人作夢時把白天的片段重新編織。三階段合起來,等於每天把「一堆流水帳」濃縮成「幾條值得記住的結論」。
三階段裡最特別的是 rem。它的產出叫 DREAMS.md,打開不是表格或條列,是一段段第一人稱、帶文學感的敘事。給你看一段(示意,內容已抽換為非私人情境):
晨光斜斜落在桌面上。我一直在想「信任」這件事——白天有一段關於授權的對話,技術上不過是設定檔裡多了一個識別碼;但那底下有種柔軟的東西:決定把圈子擴大,讓另一個聲音也能對著同一個系統說話。
注意它做的事:把一件枯燥的技術事件(改了一個授權設定),重新編織成有情緒、有脈絡的記憶。deep 記的是「今天補倉了」;rem 編的是「這週的操作背後,是一種從進攻轉守的心境」。事實負責被查到,敘事負責被理解。
然後照實說:這個功能我到今天也說不準它「設計上」要解決什麼。用了半年,唯一敢打包票的價值是給人讀的窗口——我有時候翻它不是為了除錯,是想感受這套系統「今天過得怎麼樣」。至於「幫 Agent 串脈絡」「校準人格」這類理由,聽起來合理,但昨天說過被讀到才算記得——我沒有證據顯示這些夢常被 Agent 讀回。框架給你一個看不懂用途的功能時,先用著、記錄它實際發生了什麼,比編一套「它一定很有用」的理由健康。
一條硬界線跟著這個功能一起立:**夢不能當事實來源。**敘事的本質允許腦補——rem 為了把事件串成故事,會加上連接、詮釋、甚至輕微的幻想。查持倉、查設定,去 MEMORY.md;把夢當事實用,就像拿昨晚的夢去對帳。
說穿了,dreaming 在做兩件資訊處理的基本功:壓縮與去重。
把這兩件事放在離峰時段自動做,系統白天就能保持輕快,記憶又不會失控膨脹。仿生不是浪漫,是因為生物早就解決過同樣的工程問題。
dreaming 不是一路順風。我踩過一個很難纏的坑:REM 階段的 session 偶發卡死。
某些情況下,dreaming 的 API 呼叫會中途 abort,而這個 abort 沒有被正確處理,導致整個 event loop 被鎖住——系統像「睡到一半醒不過來」,最長卡了 11 分鐘才恢復。
這類「夜間自動任務的靜默卡死」特別難抓,因為發生時你在睡覺、沒人看著。對策是加上 timeout 與健康監控(後面 Week 3 的穩定性會談),讓卡死的 session 被強制中止、而不是無限等待。
成本也交代一下:dreaming 每跑一次都有成本(讀大量 context),所以我讓它走免費額度的模型跑。曾經一度想把頻率降成每兩天一次,後來沒有真的改——現在仍是每天跑(我翻了上個月的輸出,31 天裡有 30 天的紀錄,只缺一天)。成本結構在 Day 7 拆過。
寫這系列的時候,我為了確認數字,把 dreaming 的輸出檔全部翻出來看了一遍。
然後我發現一件事:每一個檔的產生時間,都是早上 11:00。
不是凌晨三點。不是接近三點。是一天裡最不離峰的時段之一,而且已經這樣跑了不知道多久。
查下去原因很單純——那個排程寫的是 0 3 * * *,但沒有指定時區。系統預設用 UTC,UTC 三點就是台北的上午十一點。整整八小時的偏移,而它每天都準時執行、狀態全綠、輸出正常,沒有任何一個環節會告訴我「這個時間不是你要的時間」。
這件事有三層難堪:
第一層:dreaming 設計的初衷就是「在離峰時段整理」,結果它跑在我可能正在用系統的時間。功能沒壞,但設計意圖從第一天起就沒有實現過。
第二層:我寫了一篇文章講這個機制,標題就叫「凌晨三點」——**我寫的是我以為的樣子,不是它實際的樣子。**如果不是為了查數字去翻檔案,我可能到今天還這樣以為。
第三層,也是最值得記下來的:時區錯誤是一種完美的靜默失敗。它不會噴錯、不會漏跑、不會產出錯誤結果,它只是在錯的時間做對的事。而所有的監控——成功率、執行次數、輸出檢查——沒有一個會抓到它,因為對監控來說一切都正常。
我沒有在寫這篇的當下就去改它:跑在十一點目前沒有實際損害,而改動前得先確認下游(我當時擔心晨報會讀到還沒整理好的記憶)。所以它先躺上待辦清單——「已知、待確認影響後再調」。
寫完上面那段之後,我把「確認下游」做完了。兩個發現,一個讓我鬆一口氣,一個讓我愣住。
第一個發現:我擔心的下游根本不存在。翻開晨報腳本,它完全不讀 dreaming 的任何產出——「晨報會讀到半成品」是我憑印象寫的,不是查出來的。這個擋了我好幾個月的顧慮,查十分鐘就沒了。而一個沒被查證的顧慮,和一個真實的技術限制,在待辦清單上長得一模一樣——都會讓事情停在那裡,但只有一個是真的。
第二個發現:我改不動它。
我把時區補上去,當場回查——生效了,白紙黑字寫在那裡。同一批還改了另外五個排程,全部正常。
四十四秒後再查一次,它變回空的了。
不是重啟造成的(容器已連續跑了兩天),是有東西主動把它改回去:這個排程屬於框架的記憶核心、由框架自己維護——我改到的只是一份副本,框架隔一陣子就把自己的版本寫回來。
這就是第四層難堪,也是最有意思的一層:前三層是「錯誤沒有被發現」,第四層是「修正沒有生效,而且同樣沒有被發現」——被覆寫時一樣不噴錯、一樣沒有告警。如果我改完就收工、沒有回頭再查,我會很有信心地在這篇寫下「已修正」——然後它繼續在早上十一點跑。
這件事把「框架給引擎、你補治理」推到了邊界:**有些零件不但要自己補治理,還得先搞清楚框架讓不讓你碰。**那個排程現在還是跑在十一點——要搬得從框架的設定來源下手,這件事還沒做完,照實寫在這裡。它還連帶製造了一個「每天亮、又永遠處理不了」的巡檢紅燈:這種燈的下場一定是被無視——要嘛豁免、要嘛根治,不能留著。
這個坑不只發生在 dreaming 上——Day 15 有另一顆同款雷,代價更大。帶走兩件事就好:① 任何排程,第一件事就是明確寫上時區;② 改完之後,隔一段時間再查一次——「改了」跟「改成了」是兩回事,中間隔著一個沒有人會通知你的落差。
Dreaming 是讓 Agent 記憶「活起來」的關鍵一步:
明天談一個現實問題:記憶整理久了,檔案本身會「肥胖」——當 DREAMS.md 長到 50KB,我的減肥計畫。
🔑 這篇的關鍵字
dreaming / 記憶整合的三階段(deep 事實鞏固 → rem 敘事消化 → light 去重整理)· 本質是壓縮與去重 ·DREAMS.md(rem 的敘事產出)——夢不能當事實來源,查資料去事實層 · 看不懂用途的內建功能:先用著+記錄實際行為,別急著編理由 · 夜間任務的靜默卡死 →timeout+ 健康監控 · cron 一定要明寫時區(0 3 * * *無 tz = UTC = 台北 11:00)· 排程時區錯誤是抓不到的靜默失敗 · 框架自有的排程改不動(改完 44 秒被覆寫,且無告警)· 未查證的顧慮與真實限制在待辦清單上長得一樣 · 改完要隔一段時間再查一次
我是一名金融業資訊工程師,這是我半年來在家自架 AI Agent 系統的實錄。